package com.web.demo.demo;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

/**
 * @author sw
 * @create 2023-05-19 8:53
 */
public class UserTest {
    public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 生成含有注解的泛型实现字类
        DynamicType.Unloaded<?> dynamicType = new ByteBuddy()
                .subclass(TypeDescription.Generic.Builder.parameterizedType(Repository.class, String.class).build())  // 创建复杂类型的泛型注解
                .name(Repository.class.getPackage().getName().concat(".").concat("UserRepository"))                  // 添加类信息包括地址
                .method(ElementMatchers.named("queryData"))                                                          // 匹配处理的方法
                .intercept(MethodDelegation.to(UserRepositoryInterceptor.class))                                     // 交给委托函数
                .annotateMethod(AnnotationDescription.Builder.ofType(RpcGatewayMethod.class)
                        .define("methodName", "queryData")
                        .define("methodDesc", "查询数据")
                        .build())
                .annotateType(AnnotationDescription.Builder.ofType(RpcGatewayClazz.class)
                        .define("alias", "dataApi")
                        .define("clazzDesc", "查询数据信息")
                        .define("timeOut", 350L)
                        .build())
                .make();
        // 输出类信息到目标文件夹下
//        dynamicType.saveIn(new File(UserTest.class.getResource("/").getPath()));

//        DynamicType.Loaded<?> load = dynamicType.load(UserTest.class.getClassLoader());
        Class<?> repositoryClass = dynamicType.getClass();
        // 实例化对象
        Repository<String> repository = (Repository<String>) repositoryClass.getConstructor().newInstance();
// 测试输出
        System.out.println(repository.queryData(10001));
    }
}
